package com.example.library_common.view.edit_text_validator

import android.content.Context
import android.content.res.TypedArray
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Parcel
import android.os.Parcelable
import android.text.method.HideReturnsTransformationMethod
import android.text.method.PasswordTransformationMethod
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.PointerIcon
import androidx.appcompat.widget.AppCompatEditText
import androidx.databinding.BindingAdapter

import com.example.library_common.R
import com.example.library_common.utils.ShUtils

class EditTextValidator : AppCompatEditText {

    companion object {
        @BindingAdapter(value = ["min_length_error_msg"], requireAll = false)
        @JvmStatic
        fun setMinLengthErrorMsg(view: EditTextValidator, min_length_error_msg: String) {
            view.setMinLengthErrorMsg(min_length_error_msg)
        }
    }

    private var empty_error_msg = ""

    private var minLength_error_msg = ""

    private var minLength = -100

    private var mHideDrawable: Drawable? = null

    private var mShowDrawable: Drawable? = null

    private var v_drawable_tint = Color.BLACK

    private var mPasswordVisible = false

    private var exMethod = mutableListOf<() -> String?>()


    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        intiAttrs(attrs)
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        intiAttrs(attrs, defStyleAttr)
    }


    private fun intiAttrs(attrs: AttributeSet, defStyleAttr: Int = 0, defStyleRes: Int = 0) {
        val array =
            context.obtainStyledAttributes(
                attrs,
                R.styleable.EditTextValidator,
                defStyleAttr,
                defStyleRes
            )
        try {
            getAttrs(array)
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            array.recycle()
        }

        if (mHideDrawable != null) {
            mHideDrawable = ShUtils.tintDrawable(mHideDrawable, v_drawable_tint)
            mHideDrawable?.setBounds(
                0,
                0,
                mHideDrawable?.intrinsicWidth ?: 0,
                mHideDrawable?.intrinsicHeight ?: 0
            )
        }

        if (mShowDrawable != null) {
            mShowDrawable = ShUtils.tintDrawable(mShowDrawable, v_drawable_tint)
            mShowDrawable?.setBounds(
                0,
                0,
                mShowDrawable?.intrinsicWidth ?: 0,
                mShowDrawable?.intrinsicHeight ?: 0
            )
        }

        if (mHideDrawable != null && mShowDrawable != null) {
            if (mPasswordVisible) {
                showPassword()
            } else {
                hidePassword()
            }
        }
    }

    fun setMinLengthErrorMsg(min_length_error_msg: String){
        minLength_error_msg=min_length_error_msg
    }

    private fun getAttrs(array: TypedArray) {
        empty_error_msg =
            array.getString(R.styleable.EditTextValidator_v_empty_error_msg) ?: empty_error_msg

        minLength = array.getInteger(R.styleable.EditTextValidator_v_minLength, minLength)

        minLength_error_msg = array.getString(R.styleable.EditTextValidator_v_minLength_error_msg)
            ?: minLength_error_msg

        v_drawable_tint =
            array.getColor(R.styleable.EditTextValidator_v_drawable_tint, v_drawable_tint)


        mHideDrawable = array.getDrawable(R.styleable.EditTextValidator_v_hide_drawable)

        mShowDrawable = array.getDrawable(R.styleable.EditTextValidator_v_show_drawable)

        mPasswordVisible =
            array.getBoolean(R.styleable.EditTextValidator_v_password_visible, mPasswordVisible)
    }

    fun addExMethod(vararg m: () -> String) {
        exMethod.addAll(m)
    }

    fun validator(): String? {

        val text = text.toString()

        return when {
            text.isEmpty() -> empty_error_msg
            (minLength > 0 && text.length < minLength) -> minLength_error_msg
            else -> {
                var res: String? = null

                for (it in exMethod) {

                    res = it.invoke()

                }

                return res
            }
        }
    }

    private fun hidePassword() {
        setCompoundDrawables(
            compoundDrawables[0],
            compoundDrawables[1],
            mHideDrawable,
            compoundDrawables[3]
        )
        //        setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
        transformationMethod = PasswordTransformationMethod.getInstance()
        val text = text
        if (text != null) {
            setSelection(text.length)
        }
        mPasswordVisible = false
    }

    private fun showPassword() {
        setCompoundDrawables(
            compoundDrawables[0],
            compoundDrawables[1],
            mShowDrawable,
            compoundDrawables[3]
        )
        //        setInputType(InputType.TYPE_CLASS_TEXT |InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
        transformationMethod = HideReturnsTransformationMethod.getInstance()
        val text = text
        if (text != null) {
            setSelection(text.length)
        }
        mPasswordVisible = true
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (event.action == MotionEvent.ACTION_UP) {
            if (compoundDrawables[2] != null) {
                val x = event.x.toInt()
                val y = event.y.toInt()
                val rect = compoundDrawables[2].bounds
                val height = rect.height()
                val distance = (getHeight() - height) / 2
                val isInnerWidth = x > width - totalPaddingRight && x < width - paddingRight
                val isInnerHeight = y > distance && y < distance + height
                if (isInnerWidth && isInnerHeight) {
                    togglePasswordView()
                }
            }
        }
        return super.onTouchEvent(event)
    }

    private fun togglePasswordView() {
        if (mPasswordVisible) {
            hidePassword()
        } else {
            showPassword()
        }
    }


//    override fun onSaveInstanceState(): Parcelable? {
//        val saveState = super.onSaveInstanceState()
//        return SavedState(
//            saveState,
//            mPasswordVisible
//        )
//    }
//
//    override fun onRestoreInstanceState(state: Parcelable) {
//        val savedState: SavedState =
//            state as SavedState
//        mPasswordVisible = savedState.isPasswordVisible
//        if (mPasswordVisible) {
//            showPassword()
//        } else {
//            hidePassword()
//        }
//        super.onRestoreInstanceState(savedState.superState)
//    }
//
//    private class SavedState(superState: Parcelable?, passwordVisible: Boolean) :
//        BaseSavedState(superState) {
//        var isPasswordVisible = passwordVisible
//            private set
////
////        constructor(source: Parcel) : super(source) {
////            isPasswordVisible = source.readByte().toInt() != 0
////        }
//
//        override fun writeToParcel(out: Parcel, flags: Int) {
//            super.writeToParcel(out, flags)
//            out.writeByte((if (isPasswordVisible) 1 else 0).toByte())
//        }
//
//    }
}

